10x Home

Introduction

Welcome to the SIB Days 2020 - virtual conference Spatial Transcriptomics workshop by 10x genomics!

The purpose of this tutorial will be to walk users through some of the steps necessary to explore data produced by the 10x Genomics Visium Spatial Gene Expression Solution and the Spaceranger pipeline. We will investigate the data sets are all freely available from 10x Genomics.

Seurat Tutorial

Things to know about this workshop

  1. All files that will be used can be found at: /mnt/libs/shared_data/

[Terminal]

  1. Getting started with R and Visium data outside of Seurat at: https://support.10xgenomics.com/spatial-gene-expression/software/pipelines/latest/rkit
  2. Reference genome for all samples is GRCh38/mm10
  3. All 10x software including Spaceranger, and Loupe Browser, can be downloaded from the 10x Support Site
  4. Most Seurat figures can be controlled with patchwork because they are fundamentally ggplot objects. Some really nice examples can be found on the Patchwork GitHub

Exploring Visium Data with Seurat

Load our packages

library(Seurat)
library(ggplot2)
library(patchwork)
library(dplyr)
library(RColorBrewer)

Loading data in a Seurat object

Real Dataset for the tutorial

breast_cancer <- Load10X_Spatial(data.dir = "/mnt/libs/shared_data/human_breast_cancer_1/outs/",
                filename = "V1_Breast_Cancer_Block_A_Section_1_filtered_feature_bc_matrix.h5")

Same data just internal to 10x

breast_cancer <- Load10X_Spatial(data.dir = "/mnt/analysis/marsoc/pipestances/HWHTFDSXX/SPATIAL_RNA_COUNTER_PD/163086/HEAD/outs/", slice = "slice1")

There are a bunch of data sets hosted by the Satija lab in the Seurat Data Package.

Results

QC

Let’s have a look at some basic QC information. Keep in mind that most Seurat plots are ggplot object and can be manipulated as such.

Counts = UMI Features = Genes

plot1 <- VlnPlot(breast_cancer, features = "nCount_Spatial", pt.size = 0.1) + 
  ggtitle("UMI") +
  theme(axis.text.x = element_blank(), 
        axis.title.x = element_blank(), 
        legend.position = "right") +
  NoLegend()

plot2 <- VlnPlot(breast_cancer, features = "nFeature_Spatial", pt.size = 0.1) + 
  ggtitle("Genes") +
  theme(axis.text.x = element_blank(), 
        axis.title.x = element_blank(), 
        legend.position = "right") +
  NoLegend()

plot3 <- SpatialFeaturePlot(breast_cancer, features = "nCount_Spatial") + 
  theme(legend.position = "right")

plot4 <- SpatialFeaturePlot(breast_cancer, features = "nFeature_Spatial") +
  theme(legend.position = "right")

plot1 + plot2 + plot3  + plot4 + plot_layout(nrow = 2, ncol = 2)

Normalization

Spaceranger does normalization for clustering and DE but does not return that normalized matrix

Pre-normalization Raw UMI counts

SpatialFeaturePlot(breast_cancer, features = c("ERBB2", "CD8A"))

SE transform

  • This will take ~3-4 min.

Don’t worry about reachediteration limit warnings. See https://github.com/ChristophH/sctransform/issues/25 for discussion

Default assay will now be set to SCT

breast_cancer <- SCTransform(breast_cancer, assay = "Spatial", verbose = TRUE)
Calculating cell attributes for input UMI matrix
Variance stabilizing transformation of count matrix of size 19751 by 3822
Model formula is y ~ log_umi
Get Negative Binomial regression parameters per gene
Using 2000 genes, 3822 cells

  |                                                                                 
  |                                                                           |   0%
  |                                                                                 
  |=========                                                                  |  12%
  |                                                                                 
  |===================                                                        |  25%
  |                                                                                 
  |============================                                               |  38%
  |                                                                                 
  |======================================                                     |  50%
  |                                                                                 
  |===============================================                            |  62%
  |                                                                                 
  |========================================================                   |  75%
  |                                                                                 
  |==================================================================         |  88%
  |                                                                                 
  |===========================================================================| 100%
Found 2 outliers - those will be ignored in fitting/regularization step

Second step: Get residuals using fitted parameters for 19751 genes

  |                                                                                 
  |                                                                           |   0%
  |                                                                                 
  |=                                                                          |   1%
  |                                                                                 
  |==                                                                         |   3%
  |                                                                                 
  |===                                                                        |   4%
  |                                                                                 
  |====                                                                       |   5%
  |                                                                                 
  |=====                                                                      |   6%
  |                                                                                 
  |======                                                                     |   8%
  |                                                                                 
  |=======                                                                    |   9%
  |                                                                                 
  |========                                                                   |  10%
  |                                                                                 
  |=========                                                                  |  12%
  |                                                                                 
  |==========                                                                 |  13%
  |                                                                                 
  |===========                                                                |  14%
  |                                                                                 
  |============                                                               |  15%
  |                                                                                 
  |============                                                               |  17%
  |                                                                                 
  |=============                                                              |  18%
  |                                                                                 
  |==============                                                             |  19%
  |                                                                                 
  |===============                                                            |  21%
  |                                                                                 
  |================                                                           |  22%
  |                                                                                 
  |=================                                                          |  23%
  |                                                                                 
  |==================                                                         |  24%
  |                                                                                 
  |===================                                                        |  26%
  |                                                                                 
  |====================                                                       |  27%
  |                                                                                 
  |=====================                                                      |  28%
  |                                                                                 
  |======================                                                     |  29%
  |                                                                                 
  |=======================                                                    |  31%
  |                                                                                 
  |========================                                                   |  32%
  |                                                                                 
  |=========================                                                  |  33%
  |                                                                                 
  |==========================                                                 |  35%
  |                                                                                 
  |===========================                                                |  36%
  |                                                                                 
  |============================                                               |  37%
  |                                                                                 
  |=============================                                              |  38%
  |                                                                                 
  |==============================                                             |  40%
  |                                                                                 
  |===============================                                            |  41%
  |                                                                                 
  |================================                                           |  42%
  |                                                                                 
  |=================================                                          |  44%
  |                                                                                 
  |==================================                                         |  45%
  |                                                                                 
  |===================================                                        |  46%
  |                                                                                 
  |====================================                                       |  47%
  |                                                                                 
  |=====================================                                      |  49%
  |                                                                                 
  |======================================                                     |  50%
  |                                                                                 
  |======================================                                     |  51%
  |                                                                                 
  |=======================================                                    |  53%
  |                                                                                 
  |========================================                                   |  54%
  |                                                                                 
  |=========================================                                  |  55%
  |                                                                                 
  |==========================================                                 |  56%
  |                                                                                 
  |===========================================                                |  58%
  |                                                                                 
  |============================================                               |  59%
  |                                                                                 
  |=============================================                              |  60%
  |                                                                                 
  |==============================================                             |  62%
  |                                                                                 
  |===============================================                            |  63%
  |                                                                                 
  |================================================                           |  64%
  |                                                                                 
  |=================================================                          |  65%
  |                                                                                 
  |==================================================                         |  67%
  |                                                                                 
  |===================================================                        |  68%
  |                                                                                 
  |====================================================                       |  69%
  |                                                                                 
  |=====================================================                      |  71%
  |                                                                                 
  |======================================================                     |  72%
  |                                                                                 
  |=======================================================                    |  73%
  |                                                                                 
  |========================================================                   |  74%
  |                                                                                 
  |=========================================================                  |  76%
  |                                                                                 
  |==========================================================                 |  77%
  |                                                                                 
  |===========================================================                |  78%
  |                                                                                 
  |============================================================               |  79%
  |                                                                                 
  |=============================================================              |  81%
  |                                                                                 
  |==============================================================             |  82%
  |                                                                                 
  |==============================================================             |  83%
  |                                                                                 
  |===============================================================            |  85%
  |                                                                                 
  |================================================================           |  86%
  |                                                                                 
  |=================================================================          |  87%
  |                                                                                 
  |==================================================================         |  88%
  |                                                                                 
  |===================================================================        |  90%
  |                                                                                 
  |====================================================================       |  91%
  |                                                                                 
  |=====================================================================      |  92%
  |                                                                                 
  |======================================================================     |  94%
  |                                                                                 
  |=======================================================================    |  95%
  |                                                                                 
  |========================================================================   |  96%
  |                                                                                 
  |=========================================================================  |  97%
  |                                                                                 
  |========================================================================== |  99%
  |                                                                                 
  |===========================================================================| 100%
Computing corrected count matrix for 19751 genes

  |                                                                                 
  |                                                                           |   0%
  |                                                                                 
  |=                                                                          |   1%
  |                                                                                 
  |==                                                                         |   3%
  |                                                                                 
  |===                                                                        |   4%
  |                                                                                 
  |====                                                                       |   5%
  |                                                                                 
  |=====                                                                      |   6%
  |                                                                                 
  |======                                                                     |   8%
  |                                                                                 
  |=======                                                                    |   9%
  |                                                                                 
  |========                                                                   |  10%
  |                                                                                 
  |=========                                                                  |  12%
  |                                                                                 
  |==========                                                                 |  13%
  |                                                                                 
  |===========                                                                |  14%
  |                                                                                 
  |============                                                               |  15%
  |                                                                                 
  |============                                                               |  17%
  |                                                                                 
  |=============                                                              |  18%
  |                                                                                 
  |==============                                                             |  19%
  |                                                                                 
  |===============                                                            |  21%
  |                                                                                 
  |================                                                           |  22%
  |                                                                                 
  |=================                                                          |  23%
  |                                                                                 
  |==================                                                         |  24%
  |                                                                                 
  |===================                                                        |  26%
  |                                                                                 
  |====================                                                       |  27%
  |                                                                                 
  |=====================                                                      |  28%
  |                                                                                 
  |======================                                                     |  29%
  |                                                                                 
  |=======================                                                    |  31%
  |                                                                                 
  |========================                                                   |  32%
  |                                                                                 
  |=========================                                                  |  33%
  |                                                                                 
  |==========================                                                 |  35%
  |                                                                                 
  |===========================                                                |  36%
  |                                                                                 
  |============================                                               |  37%
  |                                                                                 
  |=============================                                              |  38%
  |                                                                                 
  |==============================                                             |  40%
  |                                                                                 
  |===============================                                            |  41%
  |                                                                                 
  |================================                                           |  42%
  |                                                                                 
  |=================================                                          |  44%
  |                                                                                 
  |==================================                                         |  45%
  |                                                                                 
  |===================================                                        |  46%
  |                                                                                 
  |====================================                                       |  47%
  |                                                                                 
  |=====================================                                      |  49%
  |                                                                                 
  |======================================                                     |  50%
  |                                                                                 
  |======================================                                     |  51%
  |                                                                                 
  |=======================================                                    |  53%
  |                                                                                 
  |========================================                                   |  54%
  |                                                                                 
  |=========================================                                  |  55%
  |                                                                                 
  |==========================================                                 |  56%
  |                                                                                 
  |===========================================                                |  58%
  |                                                                                 
  |============================================                               |  59%
  |                                                                                 
  |=============================================                              |  60%
  |                                                                                 
  |==============================================                             |  62%
  |                                                                                 
  |===============================================                            |  63%
  |                                                                                 
  |================================================                           |  64%
  |                                                                                 
  |=================================================                          |  65%
  |                                                                                 
  |==================================================                         |  67%
  |                                                                                 
  |===================================================                        |  68%
  |                                                                                 
  |====================================================                       |  69%
  |                                                                                 
  |=====================================================                      |  71%
  |                                                                                 
  |======================================================                     |  72%
  |                                                                                 
  |=======================================================                    |  73%
  |                                                                                 
  |========================================================                   |  74%
  |                                                                                 
  |=========================================================                  |  76%
  |                                                                                 
  |==========================================================                 |  77%
  |                                                                                 
  |===========================================================                |  78%
  |                                                                                 
  |============================================================               |  79%
  |                                                                                 
  |=============================================================              |  81%
  |                                                                                 
  |==============================================================             |  82%
  |                                                                                 
  |==============================================================             |  83%
  |                                                                                 
  |===============================================================            |  85%
  |                                                                                 
  |================================================================           |  86%
  |                                                                                 
  |=================================================================          |  87%
  |                                                                                 
  |==================================================================         |  88%
  |                                                                                 
  |===================================================================        |  90%
  |                                                                                 
  |====================================================================       |  91%
  |                                                                                 
  |=====================================================================      |  92%
  |                                                                                 
  |======================================================================     |  94%
  |                                                                                 
  |=======================================================================    |  95%
  |                                                                                 
  |========================================================================   |  96%
  |                                                                                 
  |=========================================================================  |  97%
  |                                                                                 
  |========================================================================== |  99%
  |                                                                                 
  |===========================================================================| 100%
Calculating gene attributes
Wall clock passed: Time difference of 2.091646 mins
Determine variable features
Set 3000 variable features
Place corrected count matrix in counts slot
Centering data matrix

  |                                                                                 
  |                                                                           |   0%
  |                                                                                 
  |===================                                                        |  25%
  |                                                                                 
  |======================================                                     |  50%
  |                                                                                 
  |========================================================                   |  75%
  |                                                                                 
  |===========================================================================| 100%
Set default assay to SCT
SpatialFeaturePlot(breast_cancer, features = c("ERBB2", "CD8A"))

From Seurat:

The default parameters in Seurat emphasize the visualization of molecular data. However, you can also adjust the size of the spots (and their transparency) to improve the visualization of the histology image, by changing the following parameters:

pt.size.factor- This will scale the size of the spots. Default is 1.6
alpha - minimum and maximum transparency. Default is c(1, 1).
Try setting to alpha c(0.1, 1), to downweight the transparency of points with lower expression
p1 <- SpatialFeaturePlot(breast_cancer, features = "IGFBP5", pt.size.factor = 1)+ 
  theme(legend.position = "right") +
  ggtitle("Actual Spot Size")
p2 <- SpatialFeaturePlot(breast_cancer, features = "IGFBP5")+ 
  theme(legend.position = "right") +
  ggtitle("Scaled Spot Size")
p1 + p2

Dimensionality reduction, clustering, and visualization

We can then proceed to run dimensionality reduction and clustering on the RNA expression data, using the same workflow as we use for scRNA-seq analysis.

Some of these processes can be parallized

library(future)
# check the current active plan
plan()
# change the current plan to access parallelization
plan("multiprocess", workers = 4)
plan()

The default UMAP calculation is performed with the R-based UWOT library However, you can run UMAP in python via reticulate library and umap-learn. We have found that for smaller data sets (<= 10k cells/spots) UWOT is great. For much larger data sets (100k + cells/spots) umap-learn can be a faster option.

breast_cancer <- RunPCA(breast_cancer, assay = "SCT", verbose = FALSE)
breast_cancer <- FindNeighbors(breast_cancer, reduction = "pca", dims = 1:30)
Computing nearest neighbor graph
Computing SNN
breast_cancer <- FindClusters(breast_cancer, verbose = FALSE)
breast_cancer <- RunUMAP(breast_cancer, reduction = "pca", dims = 1:30)
The default method for RunUMAP has changed from calling Python UMAP via reticulate to the R-native UWOT using the cosine metric
To use Python UMAP via reticulate, set umap.method to 'umap-learn' and metric to 'correlation'
This message will be shown once per session11:22:48 UMAP embedding parameters a = 0.9922 b = 1.112
11:22:48 Read 3822 rows and found 30 numeric columns
11:22:48 Using Annoy for neighbor search, n_neighbors = 30
11:22:48 Building Annoy index with metric = cosine, n_trees = 50
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
11:22:48 Writing NN index file to temp file /tmp/RtmpHLaSG1/file707f428273fa9
11:22:48 Searching Annoy index using 1 thread, search_k = 3000
11:22:49 Annoy recall = 100%
11:22:50 Commencing smooth kNN distance calibration using 1 thread
11:22:50 Initializing from normalized Laplacian + noise
11:22:54 Commencing optimization for 500 epochs, with 157848 positive edges
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
11:23:03 Optimization finished

Now let’s have a look at the clustering

DimPlot(breast_cancer, reduction = "umap", label = FALSE,) +
  labs(color = "Cluster")

p1 <- DimPlot(breast_cancer, reduction = "umap", label = TRUE) +
  labs(color = "Cluster")
p2 <- SpatialDimPlot(breast_cancer, label = TRUE, label.size = 3) +
  labs(fill = "Cluster")

p1 + p2 + plot_annotation(
  title = 'Clustering in UMAP and Tissue Space',
  caption = 'Processed by Spaceranger 1.1\nNormilization and Clustering by Seurat'
) + plot_layout(nrow = 1)

I don’t really like these colors so let’s change them

myPalette <- colorRampPalette(rev(brewer.pal(11, "Spectral")))
p1 <- DimPlot(breast_cancer, reduction = "umap", label = TRUE) +
  labs(color = "Cluster") + 
  scale_color_manual(values = c("#b2df8a","#e41a1c","#377eb8","#4daf4a","#ff7f00","gold", 
                               "#a65628", "#999999", "black", "pink", "purple", "brown",
                               "grey", "yellow", "green"))

p2 <- SpatialDimPlot(breast_cancer, label = TRUE, label.size = 3) +
  labs(fill = "Cluster")+ 
  scale_fill_manual(values = c("#b2df8a","#e41a1c","#377eb8","#4daf4a","#ff7f00","gold", 
                               "#a65628", "#999999", "black", "pink", "purple", "brown",
                               "grey", "yellow", "green"))

p1 + p2 + plot_annotation(
  title = 'Clustering in UMAP and Tissue Space',
  caption = 'Processed by Spaceranger 1.1\nNormilization and Clustering by Seurat'
) + plot_layout(nrow = 1)

If interested you can also now look at UMI and Gene counts per cluster as well

plot1 <- VlnPlot(breast_cancer, features = "nCount_Spatial", pt.size = 0.1) + 
  ggtitle("UMI") +
  scale_fill_manual(values = c("#b2df8a","#e41a1c","#377eb8","#4daf4a","#ff7f00","gold", 
                               "#a65628", "#999999", "black", "pink", "purple", "brown",
                               "grey", "yellow", "green"))+
  theme(axis.text.x = element_blank(), 
        axis.title.x = element_blank(), 
        legend.position = "right") +
  NoLegend()

plot2 <- VlnPlot(breast_cancer, features = "nFeature_Spatial", pt.size = 0.1) + 
  ggtitle("Genes") +
  scale_fill_manual(values = c("#b2df8a","#e41a1c","#377eb8","#4daf4a","#ff7f00","gold", 
                               "#a65628", "#999999", "black", "pink", "purple", "brown",
                               "grey", "yellow", "green"))+
  theme(axis.title.x = element_blank(), 
        legend.position = "right") +
  NoLegend()

plot1 + plot2

Now let’s take a look at at a gene of interest with violin plots but also in image space.

p1 <- VlnPlot(breast_cancer, features = "IGFBP5", pt.size = 0.1) + 
  ggtitle("IGFBP5") +
  scale_fill_manual(values = c("#b2df8a","#e41a1c","#377eb8","#4daf4a","#ff7f00","gold", 
                               "#a65628", "#999999", "black", "pink", "purple", "brown",
                               "grey", "yellow", "green"))+
  theme(axis.title.x = element_blank(), 
        legend.position = "right") +
  NoLegend() +
  stat_summary(fun=mean, geom="point", shape=23, size=4, color="red")

p2 <- SpatialFeaturePlot(breast_cancer, features = "IGFBP5")+ 
  theme(legend.position = "right")
CombinePlots is being deprecated. Plots should now be combined using the patchwork system.
p3 <- SpatialDimPlot(breast_cancer, label = TRUE, label.size = 3) +
  labs(fill = "Cluster")+ 
  scale_fill_manual(values = c("#b2df8a","#e41a1c","#377eb8","#4daf4a","#ff7f00","gold", 
                               "#a65628", "#999999", "black", "pink", "purple", "brown",
                               "grey", "yellow", "green")) +
  NoLegend()
CombinePlots is being deprecated. Plots should now be combined using the patchwork system.
row1 <- p2 + p3 + plot_layout(nrow = 1)
row1 + p1+ plot_layout(nrow = 2, widths = c(0.5, 0.5))

We can also look at these data interactively

LinkedDimPlot(breast_cancer)

Spatially variable features

First we’ll identify deferentially expressed genes.

Parallelization helps here too let’s make sure our plan is still intact

plan()
Error in plan() : could not find function "plan"

- call: plan("multiprocess", workers = 4) indicates that it is

Looks like we have some very DE genes for clusters 4 and 11

clarify what ident.1 = 4, ident.2 = 6 are for

de_markers <- FindMarkers(breast_cancer, ident.1 = 4, ident.2 = 6)

  |                                                  | 0 % ~calculating  
  |+                                                 | 1 % ~32s          
  |++                                                | 2 % ~32s          
  |++                                                | 3 % ~31s          
  |+++                                               | 4 % ~31s          
  |+++                                               | 5 % ~31s          
  |++++                                              | 6 % ~30s          
  |++++                                              | 7 % ~30s          
  |+++++                                             | 8 % ~29s          
  |+++++                                             | 9 % ~29s          
  |++++++                                            | 10% ~28s          
  |++++++                                            | 11% ~28s          
  |+++++++                                           | 12% ~28s          
  |+++++++                                           | 13% ~27s          
  |++++++++                                          | 14% ~27s          
  |++++++++                                          | 15% ~27s          
  |+++++++++                                         | 16% ~26s          
  |+++++++++                                         | 17% ~26s          
  |++++++++++                                        | 18% ~26s          
  |++++++++++                                        | 19% ~25s          
  |+++++++++++                                       | 20% ~25s          
  |+++++++++++                                       | 21% ~24s          
  |++++++++++++                                      | 22% ~24s          
  |++++++++++++                                      | 23% ~24s          
  |+++++++++++++                                     | 24% ~24s          
  |+++++++++++++                                     | 26% ~23s          
  |++++++++++++++                                    | 27% ~23s          
  |++++++++++++++                                    | 28% ~23s          
  |+++++++++++++++                                   | 29% ~22s          
  |+++++++++++++++                                   | 30% ~22s          
  |++++++++++++++++                                  | 31% ~22s          
  |++++++++++++++++                                  | 32% ~21s          
  |+++++++++++++++++                                 | 33% ~21s          
  |+++++++++++++++++                                 | 34% ~21s          
  |++++++++++++++++++                                | 35% ~20s          
  |++++++++++++++++++                                | 36% ~20s          
  |+++++++++++++++++++                               | 37% ~20s          
  |+++++++++++++++++++                               | 38% ~19s          
  |++++++++++++++++++++                              | 39% ~19s          
  |++++++++++++++++++++                              | 40% ~19s          
  |+++++++++++++++++++++                             | 41% ~18s          
  |+++++++++++++++++++++                             | 42% ~18s          
  |++++++++++++++++++++++                            | 43% ~18s          
  |++++++++++++++++++++++                            | 44% ~17s          
  |+++++++++++++++++++++++                           | 45% ~17s          
  |+++++++++++++++++++++++                           | 46% ~17s          
  |++++++++++++++++++++++++                          | 47% ~17s          
  |++++++++++++++++++++++++                          | 48% ~16s          
  |+++++++++++++++++++++++++                         | 49% ~16s          
  |+++++++++++++++++++++++++                         | 50% ~16s          
  |++++++++++++++++++++++++++                        | 51% ~15s          
  |+++++++++++++++++++++++++++                       | 52% ~15s          
  |+++++++++++++++++++++++++++                       | 53% ~15s          
  |++++++++++++++++++++++++++++                      | 54% ~14s          
  |++++++++++++++++++++++++++++                      | 55% ~14s          
  |+++++++++++++++++++++++++++++                     | 56% ~14s          
  |+++++++++++++++++++++++++++++                     | 57% ~13s          
  |++++++++++++++++++++++++++++++                    | 58% ~13s          
  |++++++++++++++++++++++++++++++                    | 59% ~13s          
  |+++++++++++++++++++++++++++++++                   | 60% ~12s          
  |+++++++++++++++++++++++++++++++                   | 61% ~12s          
  |++++++++++++++++++++++++++++++++                  | 62% ~12s          
  |++++++++++++++++++++++++++++++++                  | 63% ~11s          
  |+++++++++++++++++++++++++++++++++                 | 64% ~11s          
  |+++++++++++++++++++++++++++++++++                 | 65% ~11s          
  |++++++++++++++++++++++++++++++++++                | 66% ~11s          
  |++++++++++++++++++++++++++++++++++                | 67% ~10s          
  |+++++++++++++++++++++++++++++++++++               | 68% ~10s          
  |+++++++++++++++++++++++++++++++++++               | 69% ~10s          
  |++++++++++++++++++++++++++++++++++++              | 70% ~09s          
  |++++++++++++++++++++++++++++++++++++              | 71% ~09s          
  |+++++++++++++++++++++++++++++++++++++             | 72% ~09s          
  |+++++++++++++++++++++++++++++++++++++             | 73% ~08s          
  |++++++++++++++++++++++++++++++++++++++            | 74% ~08s          
  |++++++++++++++++++++++++++++++++++++++            | 76% ~08s          
  |+++++++++++++++++++++++++++++++++++++++           | 77% ~07s          
  |+++++++++++++++++++++++++++++++++++++++           | 78% ~07s          
  |++++++++++++++++++++++++++++++++++++++++          | 79% ~07s          
  |++++++++++++++++++++++++++++++++++++++++          | 80% ~06s          
  |+++++++++++++++++++++++++++++++++++++++++         | 81% ~06s          
  |+++++++++++++++++++++++++++++++++++++++++         | 82% ~06s          
  |++++++++++++++++++++++++++++++++++++++++++        | 83% ~05s          
  |++++++++++++++++++++++++++++++++++++++++++        | 84% ~05s          
  |+++++++++++++++++++++++++++++++++++++++++++       | 85% ~05s          
  |+++++++++++++++++++++++++++++++++++++++++++       | 86% ~05s          
  |++++++++++++++++++++++++++++++++++++++++++++      | 87% ~04s          
  |++++++++++++++++++++++++++++++++++++++++++++      | 88% ~04s          
  |+++++++++++++++++++++++++++++++++++++++++++++     | 89% ~04s          
  |+++++++++++++++++++++++++++++++++++++++++++++     | 90% ~03s          
  |++++++++++++++++++++++++++++++++++++++++++++++    | 91% ~03s          
  |++++++++++++++++++++++++++++++++++++++++++++++    | 92% ~03s          
  |+++++++++++++++++++++++++++++++++++++++++++++++   | 93% ~02s          
  |+++++++++++++++++++++++++++++++++++++++++++++++   | 94% ~02s          
  |++++++++++++++++++++++++++++++++++++++++++++++++  | 95% ~02s          
  |++++++++++++++++++++++++++++++++++++++++++++++++  | 96% ~01s          
  |+++++++++++++++++++++++++++++++++++++++++++++++++ | 97% ~01s          
  |+++++++++++++++++++++++++++++++++++++++++++++++++ | 98% ~01s          
  |++++++++++++++++++++++++++++++++++++++++++++++++++| 99% ~00s          
  |++++++++++++++++++++++++++++++++++++++++++++++++++| 100% elapsed=31s  
de_markers

Identify the most up-regulated and down-regulated genes

de_markers_up <- de_markers %>%
  tibble::rownames_to_column(var = "Gene") %>% 
  arrange(-avg_logFC)

de_markers_down <- de_markers %>%
  tibble::rownames_to_column(var = "Gene") %>% 
  arrange(avg_logFC)

Most up-regulated genes

SpatialFeaturePlot(object = breast_cancer, features = de_markers_up$Gene[1:10], alpha = c(0.1, 1), ncol = 3)

Most down-regulated genes

SpatialFeaturePlot(object = breast_cancer, features = de_markers_down$Gene[1:10], alpha = c(0.1, 1), ncol = 3)

what are the top variable features?

VariableFeatures(breast_cancer)[1:10]
 [1] "IGKC"   "IGHG3"  "IGLC2"  "MGP"    "ALB"    "IGHG1"  "CPB1"   "CRISP3" "IGLC3" 
[10] "IGHM"  

what are the top DE genes?

rownames(de_markers)[1:10]
 [1] "CRISP3"  "IGFBP5"  "SLITRK6" "H3F3A"   "IGFBP4"  "MALAT1"  "C3"      "KRT18"  
 [9] "S100A11" "MGP"    

Spatially Variable Genes

So what about spatial enrichment?

Some methods

  1. Trendsceek
  2. Splotch
  3. SPARK
  4. SpatialDE
  • We have found this implementation not to be very effective. It’s also not under active development

Using the top 100 variable genes find spatially enriched ones. Note that in the Seurat Spatial Tutorial they use 1000 genes. You can also use all genes but that will take a long time. Using a calculation of Morans I can sometimes be a faster approach, especially if you are using parallization.

breast_cancer <- FindSpatiallyVariableFeatures(breast_cancer, 
                                               assay = "SCT", 
                                               slot = "scale.data", 
                                               features = VariableFeatures(breast_cancer)[1:100],
                                               selection.method = "markvariogram", verbose = TRUE)

Have a look at the spatially variable genes calculated by markvariogram ordered from most variable to least variable

SpatiallyVariableFeatures(breast_cancer, selection.method = "markvariogram", decreasing = TRUE)
  [1] "CRISP3"     "CXCL14"     "MGP"        "CPB1"       "COX6C"      "SLITRK6"   
  [7] "TTLL12"     "CCND1"      "MALAT1"     "AGR2"       "ALB"        "GFRA1"     
 [13] "S100G"      "CSTA"       "DEGS1"      "TFF3"       "MT-ND1"     "IGLC2"     
 [19] "MT-CO1"     "IGHG3"      "CD74"       "C6orf141"   "S100A6"     "MT-ND2"    
 [25] "TFF1"       "IGKC"       "IGHG1"      "APOE"       "ZNF350-AS1" "HLA-DRA"   
 [31] "AC087379.2" "IGHG4"      "C3"         "FCGR3B"     "TIMP1"      "LINC00645" 
 [37] "IGHM"       "SCGB2A2"    "KRT14"      "IGLC3"      "KRT17"      "LYZ"       
 [43] "APOC1"      "SCGB1D2"    "IGHA1"      "C1QA"       "AEBP1"      "APOD"      
 [49] "KRT5"       "MMP7"       "CCL19"      "COL6A2"     "TAGLN"      "S100A9"    
 [55] "IGHG2"      "COL1A2"     "DCN"        "SPP1"       "COL1A1"     "CGA"       
 [61] "VIM"        "IGFBP7"     "FN1"        "CCDC80"     "CXCL9"      "IGHA2"     
 [67] "TRBC2"      "SFRP2"      "KRT6B"      "S100A2"     "LUM"        "COL3A1"    
 [73] "IGLC7"      "SAA1"       "CARTPT"     "COMP"       "JCHAIN"     "CST1"      
 [79] "PTGDS"      "SFRP4"      "CD79A"      "CCL21"      "FABP4"      "MUC19"     
 [85] "ACKR1"      "POSTN"      "MMP9"       "S100A7"     "VWF"        "AQP1"      
 [91] "CLDN5"      "ACTA2"      "MS4A1"      "IGLL5"      "MYH11"      "CXCL10"    
 [97] "IGHD"       "HBB"        "TPSB2"      "AC005224.3"
top.features_trendseq <- head(SpatiallyVariableFeatures(breast_cancer, selection.method = "markvariogram"), 8)
SpatialFeaturePlot(breast_cancer, features = top.features_trendseq, ncol = 4, alpha = c(0.1, 1))

Moran’s I implementation. For other spatial data types the x.cuts and y.cuts determines the grid that is laid over the tissue in the capture area. Here we’ll remove those

breast_cancer <- FindSpatiallyVariableFeatures(breast_cancer, 
                                               assay = "SCT", 
                                               slot = "scale.data", 
                                               features = VariableFeatures(breast_cancer)[1:100],
                                               selection.method = "moransi")
Computing Moran's I

Have a look at the spatially variable genes calculated by moransi ordered from most variable to least variable

SpatiallyVariableFeatures(breast_cancer, selection.method = "moransi", decreasing = TRUE)
  [1] "CRISP3"     "CXCL14"     "TTLL12"     "SLITRK6"    "GFRA1"      "CCND1"     
  [7] "AGR2"       "COX6C"      "MGP"        "ALB"        "MALAT1"     "CPB1"      
 [13] "DEGS1"      "C6orf141"   "CSTA"       "MT-ND1"     "TFF3"       "MT-CO1"    
 [19] "S100A6"     "MT-ND2"     "LINC00645"  "FCGR3B"     "S100G"      "TFF1"      
 [25] "C3"         "ZNF350-AS1" "HLA-DRA"    "CD74"       "SCGB1D2"    "APOD"      
 [31] "IGLC2"      "TIMP1"      "IGHG3"      "SCGB2A2"    "APOC1"      "KRT14"     
 [37] "LYZ"        "CCDC80"     "APOE"       "TAGLN"      "IGHG1"      "AC087379.2"
 [43] "CCL19"      "SPP1"       "IGKC"       "S100A9"     "KRT17"      "IGHM"      
 [49] "FN1"        "KRT5"       "IGFBP7"     "C1QA"       "COL6A2"     "AQP1"      
 [55] "CXCL9"      "ACKR1"      "CARTPT"     "DCN"        "AEBP1"      "IGLC3"     
 [61] "IGHG4"      "VIM"        "S100A2"     "IGHG2"      "MMP7"       "IGHA1"     
 [67] "CCL21"      "KRT6B"      "TRBC2"      "COL1A2"     "CGA"        "SFRP2"     
 [73] "VWF"        "COL1A1"     "SAA1"       "MUC19"      "COL3A1"     "CLDN5"     
 [79] "SFRP4"      "POSTN"      "PTGDS"      "IGHA2"      "JCHAIN"     "CD79A"     
 [85] "ACTA2"      "LUM"        "CST1"       "S100A7"     "COMP"       "MS4A1"     
 [91] "IGLC7"      "MMP9"       "HBB"        "FABP4"      "MYH11"      "IGLL5"     
 [97] "CXCL10"     "TPSB2"      "IGHD"       "AC005224.3"
top.features_moransi <- head(SpatiallyVariableFeatures(breast_cancer, selection.method = "moransi"), 8)
SpatialFeaturePlot(breast_cancer, features = top.features_moransi, ncol = 4, alpha = c(0.1, 1))

We can see that the results are slightly different. So let’s take a look at why.

spatially_variable_genes <- breast_cancer@assays$SCT@meta.features %>%
  tidyr::drop_na()

spatially_variable_genes

You can see the two methods show

mm_cor <- cor.test(spatially_variable_genes$moransi.spatially.variable.rank, spatially_variable_genes$markvariogram.spatially.variable.rank)
ggplot(spatially_variable_genes, aes(x=moransi.spatially.variable.rank,y=markvariogram.spatially.variable.rank))+
  geom_point()+
  geom_smooth()+
  xlab("Morans I Rank")+
  ylab("Markvariogram Rank")+
  annotate("text", x = 25, y = 75, label = paste("Pearson's Correlation\n", round(mm_cor$estimate[1], digits = 2), sep = ""))+
  theme_bw()

Cancer annotations

Where are these genes being expressed relative to pathologist annotation?

ca <- readbitmap::read.bitmap("images/Breast Cancer Path.png")
# in the tutorial
# ca <- readbitmap::read.bitmap('/mnt/libs/shared_data/human_breast_cancer_1/images/Breast_Cancer_Path.png')
plot(0:1,0:1,type="n",ann=FALSE,axes=FALSE)
rasterImage(ca,0,0,1,1)

Looks like the Matrix Gla protein ( MGP ) gene is enriched in Ductal Carcinoma In Situ. Not a lot is known about MGP in the context of cancer but it looks like it could be an interesting novel gene to investigate with regard to Ductal Carcinoma In Situ.

SpatialFeaturePlot(object = breast_cancer, features = "MGP", alpha = c(0.1, 1), ncol = 3)

Multiple Sections

for workshop

breast_cancer_2 <- Load10X_Spatial(data.dir = "/mnt/libs/shared_data/human_breast_cancer_2/outs/",
                filename = "V1_Breast_Cancer_Block_A_Section_2_filtered_feature_bc_matrix.h5")

for 10x

breast_cancer_2 <- Load10X_Spatial(data.dir = "/mnt/analysis/marsoc/pipestances/HWHTFDSXX/SPATIAL_RNA_COUNTER_PD/163087/HEAD/outs/", 
                                   slice = "slice2")
breast_cancer_merged <- merge(breast_cancer, breast_cancer_2)
Some cell names are duplicated across objects provided. Renaming to enforce unique cell names.

Counts = UMI Features = Genes

plot1 <- SpatialFeaturePlot(breast_cancer_merged, features = "nCount_Spatial") + 
  theme(legend.position = "right")

plot2 <- SpatialFeaturePlot(breast_cancer_merged, features = "nFeature_Spatial") +
  theme(legend.position = "right")

plot1 + plot2 + plot_layout(nrow = 2)

Normalize merged data

This will take ~3min

Default assay will now be set to SCT

breast_cancer_merged <- SCTransform(breast_cancer_merged, assay = "Spatial", verbose = TRUE)
Calculating cell attributes for input UMI matrix
Variance stabilizing transformation of count matrix of size 20963 by 7834
Model formula is y ~ log_umi
Get Negative Binomial regression parameters per gene
Using 2000 genes, 7834 cells

  |                                                                                 
  |                                                                           |   0%
  |                                                                                 
  |=========                                                                  |  12%
  |                                                                                 
  |===================                                                        |  25%
  |                                                                                 
  |============================                                               |  38%
  |                                                                                 
  |======================================                                     |  50%
  |                                                                                 
  |===============================================                            |  62%
  |                                                                                 
  |========================================================                   |  75%
  |                                                                                 
  |==================================================================         |  88%
  |                                                                                 
  |===========================================================================| 100%
Found 4 outliers - those will be ignored in fitting/regularization step

Second step: Get residuals using fitted parameters for 20963 genes

  |                                                                                 
  |                                                                           |   0%
  |                                                                                 
  |=                                                                          |   1%
  |                                                                                 
  |==                                                                         |   2%
  |                                                                                 
  |===                                                                        |   4%
  |                                                                                 
  |====                                                                       |   5%
  |                                                                                 
  |=====                                                                      |   6%
  |                                                                                 
  |=====                                                                      |   7%
  |                                                                                 
  |======                                                                     |   9%
  |                                                                                 
  |=======                                                                    |  10%
  |                                                                                 
  |========                                                                   |  11%
  |                                                                                 
  |=========                                                                  |  12%
  |                                                                                 
  |==========                                                                 |  13%
  |                                                                                 
  |===========                                                                |  15%
  |                                                                                 
  |============                                                               |  16%
  |                                                                                 
  |=============                                                              |  17%
  |                                                                                 
  |==============                                                             |  18%
  |                                                                                 
  |===============                                                            |  20%
  |                                                                                 
  |================                                                           |  21%
  |                                                                                 
  |================                                                           |  22%
  |                                                                                 
  |=================                                                          |  23%
  |                                                                                 
  |==================                                                         |  24%
  |                                                                                 
  |===================                                                        |  26%
  |                                                                                 
  |====================                                                       |  27%
  |                                                                                 
  |=====================                                                      |  28%
  |                                                                                 
  |======================                                                     |  29%
  |                                                                                 
  |=======================                                                    |  30%
  |                                                                                 
  |========================                                                   |  32%
  |                                                                                 
  |=========================                                                  |  33%
  |                                                                                 
  |==========================                                                 |  34%
  |                                                                                 
  |===========================                                                |  35%
  |                                                                                 
  |===========================                                                |  37%
  |                                                                                 
  |============================                                               |  38%
  |                                                                                 
  |=============================                                              |  39%
  |                                                                                 
  |==============================                                             |  40%
  |                                                                                 
  |===============================                                            |  41%
  |                                                                                 
  |================================                                           |  43%
  |                                                                                 
  |=================================                                          |  44%
  |                                                                                 
  |==================================                                         |  45%
  |                                                                                 
  |===================================                                        |  46%
  |                                                                                 
  |====================================                                       |  48%
  |                                                                                 
  |=====================================                                      |  49%
  |                                                                                 
  |======================================                                     |  50%
  |                                                                                 
  |======================================                                     |  51%
  |                                                                                 
  |=======================================                                    |  52%
  |                                                                                 
  |========================================                                   |  54%
  |                                                                                 
  |=========================================                                  |  55%
  |                                                                                 
  |==========================================                                 |  56%
  |                                                                                 
  |===========================================                                |  57%
  |                                                                                 
  |============================================                               |  59%
  |                                                                                 
  |=============================================                              |  60%
  |                                                                                 
  |==============================================                             |  61%
  |                                                                                 
  |===============================================                            |  62%
  |                                                                                 
  |================================================                           |  63%
  |                                                                                 
  |================================================                           |  65%
  |                                                                                 
  |=================================================                          |  66%
  |                                                                                 
  |==================================================                         |  67%
  |                                                                                 
  |===================================================                        |  68%
  |                                                                                 
  |====================================================                       |  70%
  |                                                                                 
  |=====================================================                      |  71%
  |                                                                                 
  |======================================================                     |  72%
  |                                                                                 
  |=======================================================                    |  73%
  |                                                                                 
  |========================================================                   |  74%
  |                                                                                 
  |=========================================================                  |  76%
  |                                                                                 
  |==========================================================                 |  77%
  |                                                                                 
  |===========================================================                |  78%
  |                                                                                 
  |===========================================================                |  79%
  |                                                                                 
  |============================================================               |  80%
  |                                                                                 
  |=============================================================              |  82%
  |                                                                                 
  |==============================================================             |  83%
  |                                                                                 
  |===============================================================            |  84%
  |                                                                                 
  |================================================================           |  85%
  |                                                                                 
  |=================================================================          |  87%
  |                                                                                 
  |==================================================================         |  88%
  |                                                                                 
  |===================================================================        |  89%
  |                                                                                 
  |====================================================================       |  90%
  |                                                                                 
  |=====================================================================      |  91%
  |                                                                                 
  |======================================================================     |  93%
  |                                                                                 
  |======================================================================     |  94%
  |                                                                                 
  |=======================================================================    |  95%
  |                                                                                 
  |========================================================================   |  96%
  |                                                                                 
  |=========================================================================  |  98%
  |                                                                                 
  |========================================================================== |  99%
  |                                                                                 
  |===========================================================================| 100%
Computing corrected count matrix for 20963 genes

  |                                                                                 
  |                                                                           |   0%
  |                                                                                 
  |=                                                                          |   1%
  |                                                                                 
  |==                                                                         |   2%
  |                                                                                 
  |===                                                                        |   4%
  |                                                                                 
  |====                                                                       |   5%
  |                                                                                 
  |=====                                                                      |   6%
  |                                                                                 
  |=====                                                                      |   7%
  |                                                                                 
  |======                                                                     |   9%
  |                                                                                 
  |=======                                                                    |  10%
  |                                                                                 
  |========                                                                   |  11%
  |                                                                                 
  |=========                                                                  |  12%
  |                                                                                 
  |==========                                                                 |  13%
  |                                                                                 
  |===========                                                                |  15%
  |                                                                                 
  |============                                                               |  16%
  |                                                                                 
  |=============                                                              |  17%
  |                                                                                 
  |==============                                                             |  18%
  |                                                                                 
  |===============                                                            |  20%
  |                                                                                 
  |================                                                           |  21%
  |                                                                                 
  |================                                                           |  22%
  |                                                                                 
  |=================                                                          |  23%
  |                                                                                 
  |==================                                                         |  24%
  |                                                                                 
  |===================                                                        |  26%
  |                                                                                 
  |====================                                                       |  27%
  |                                                                                 
  |=====================                                                      |  28%
  |                                                                                 
  |======================                                                     |  29%
  |                                                                                 
  |=======================                                                    |  30%
  |                                                                                 
  |========================                                                   |  32%
  |                                                                                 
  |=========================                                                  |  33%
  |                                                                                 
  |==========================                                                 |  34%
  |                                                                                 
  |===========================                                                |  35%
  |                                                                                 
  |===========================                                                |  37%
  |                                                                                 
  |============================                                               |  38%
  |                                                                                 
  |=============================                                              |  39%
  |                                                                                 
  |==============================                                             |  40%
  |                                                                                 
  |===============================                                            |  41%
  |                                                                                 
  |================================                                           |  43%
  |                                                                                 
  |=================================                                          |  44%
  |                                                                                 
  |==================================                                         |  45%
  |                                                                                 
  |===================================                                        |  46%
  |                                                                                 
  |====================================                                       |  48%
  |                                                                                 
  |=====================================                                      |  49%
  |                                                                                 
  |======================================                                     |  50%
  |                                                                                 
  |======================================                                     |  51%
  |                                                                                 
  |=======================================                                    |  52%
  |                                                                                 
  |========================================                                   |  54%
  |                                                                                 
  |=========================================                                  |  55%
  |                                                                                 
  |==========================================                                 |  56%
  |                                                                                 
  |===========================================                                |  57%
  |                                                                                 
  |============================================                               |  59%
  |                                                                                 
  |=============================================                              |  60%
  |                                                                                 
  |==============================================                             |  61%
  |                                                                                 
  |===============================================                            |  62%
  |                                                                                 
  |================================================                           |  63%
  |                                                                                 
  |================================================                           |  65%
  |                                                                                 
  |=================================================                          |  66%
  |                                                                                 
  |==================================================                         |  67%
  |                                                                                 
  |===================================================                        |  68%
  |                                                                                 
  |====================================================                       |  70%
  |                                                                                 
  |=====================================================                      |  71%
  |                                                                                 
  |======================================================                     |  72%
  |                                                                                 
  |=======================================================                    |  73%
  |                                                                                 
  |========================================================                   |  74%
  |                                                                                 
  |=========================================================                  |  76%
  |                                                                                 
  |==========================================================                 |  77%
  |                                                                                 
  |===========================================================                |  78%
  |                                                                                 
  |===========================================================                |  79%
  |                                                                                 
  |============================================================               |  80%
  |                                                                                 
  |=============================================================              |  82%
  |                                                                                 
  |==============================================================             |  83%
  |                                                                                 
  |===============================================================            |  84%
  |                                                                                 
  |================================================================           |  85%
  |                                                                                 
  |=================================================================          |  87%
  |                                                                                 
  |==================================================================         |  88%
  |                                                                                 
  |===================================================================        |  89%
  |                                                                                 
  |====================================================================       |  90%
  |                                                                                 
  |=====================================================================      |  91%
  |                                                                                 
  |======================================================================     |  93%
  |                                                                                 
  |======================================================================     |  94%
  |                                                                                 
  |=======================================================================    |  95%
  |                                                                                 
  |========================================================================   |  96%
  |                                                                                 
  |=========================================================================  |  98%
  |                                                                                 
  |========================================================================== |  99%
  |                                                                                 
  |===========================================================================| 100%
Calculating gene attributes
Wall clock passed: Time difference of 6.223681 mins
Determine variable features
Set 3000 variable features
Place corrected count matrix in counts slot
Centering data matrix

  |                                                                                 
  |                                                                           |   0%
  |                                                                                 
  |===================                                                        |  25%
  |                                                                                 
  |======================================                                     |  50%
  |                                                                                 
  |========================================================                   |  75%
  |                                                                                 
  |===========================================================================| 100%
Set default assay to SCT
SpatialFeaturePlot(breast_cancer_merged, features = c("ERBB2", "CD8A"))

Single cell/nuclei ingegration

Here we have a preprocessed Seurat object with 10k nuclei annotated from a breast cancer sample. Don’t bother too much with the details of how this data was generated they don’t particularly matter for our purposes.

Load the Seurat object

10x infrastructure

load("/mnt/home/stephen.williams/yard/Odin/SIB_2020_Workshop/bc_snRNA.rds")
file ‘bc_snRNA.rds’ has magic number 'X'
  Use of save versions prior to 2 is deprecatedError in load("/mnt/home/stephen.williams/yard/Odin/SIB_2020_Workshop/bc_snRNA.rds") : 
  bad restore file magic number (file may be corrupted) -- no data loaded

For the workshop

bc_snRNA <- readRDS("/mnt/libs/shared_data/bc_snRNA.rds")
bc_snRNA
An object of class Seurat 
61450 features across 10000 samples within 2 assays 
Active assay: SCT (27912 features)
 1 other assay present: RNA
 3 dimensional reductions calculated: pca, harmony, umap

LS0tCnRpdGxlOiAiU0lCIERheXMgMjAyMCAtIFZpcnR1YWwgQ29uZmVyZW5jZSAtIEp1bmUgOCwgMjAyMCIKc3VidGl0bGU6ICJEYXRhc2V0OiBCcmVhc3QgQ2FuY2VyIgphdXRob3I6CiAgLSBQYXRyaWNrIFJvZWxsaSwgQ29tcHV0YXRpb25hbCBCaW9sb2dpc3QgMiAtIENvbXB1dGF0aW9uYWwgQmlvbG9neV5bMTB4IEdlbm9taWNzLCBwYXRyaWNrLnJvZWxsaUAxMHhnZW5vbWljcy5jb20gXQogIC0gU3RlZmFuaWEgR2lhY29tZWxsbywgQ29tcHV0YXRpb25hbCBCaW9sb2dpc3QgMiAtIENvbXB1dGF0aW9uYWwgQmlvbG9neV5bMTB4IEdlbm9taWNzLCBzdGVmYW5pYS5naWFjb21lbGxvQDEweGdlbm9taWNzLmNvbV0KICAtIFN0ZXBoZW4gV2lsbGlhbXMsIFNlbmlvciBTY2llbnRpc3QgLSBDb21wdXRhdGlvbmFsIEJpb2xvZ3leWzEweCBHZW5vbWljcywgc3RlcGhlbi53aWxsaWFtc0AxMHhnZW5vbWljcy5jb21dCmRhdGU6ICdMYXN0IENvbXBpbGVkOiBgciBmb3JtYXQoU3lzLkRhdGUoKSwgIiVCICVkLCAlWSIpYCcKb3V0cHV0OgogIGh0bWxfbm90ZWJvb2s6CiAgICBjb2RlX2ZvbGRpbmc6IG5vbmUKICAgIHRoZW1lOiBqb3VybmFsCiAgICB0b2M6IHllcwogICAgdG9jX2RlcHRoOiAzCiAgICB0b2NfZmxvYXQ6IHllcwotLS0KClshWzEweCBIb21lXShodHRwczovL2dpdGh1Yi5jb20vc3RlcGhlbndpbGxpYW1zMjIvU0lCXzIwMjBfV29ya3Nob3AvcmF3L21hc3Rlci9pbWFnZXMvMTB4JTIwaG9tZXBhZ2UucG5nKV0oaHR0cHM6Ly93d3cuMTB4Z2Vub21pY3MuY29tLykKCiMgKipJbnRyb2R1Y3Rpb24qKgoKV2VsY29tZSB0byB0aGUgKipTSUIgRGF5cyAyMDIwIC0gdmlydHVhbCBjb25mZXJlbmNlKiogU3BhdGlhbCBUcmFuc2NyaXB0b21pY3Mgd29ya3Nob3AgYnkgMTB4IGdlbm9taWNzIQoKVGhlIHB1cnBvc2Ugb2YgdGhpcyB0dXRvcmlhbCB3aWxsIGJlIHRvIHdhbGsgdXNlcnMgdGhyb3VnaCBzb21lIG9mIHRoZSBzdGVwcyBuZWNlc3NhcnkgdG8gZXhwbG9yZSBkYXRhIHByb2R1Y2VkIGJ5IHRoZSAxMHggR2Vub21pY3MgVmlzaXVtIFNwYXRpYWwgR2VuZSBFeHByZXNzaW9uIFNvbHV0aW9uIGFuZCB0aGUgW1NwYWNlcmFuZ2VyIHBpcGVsaW5lXShodHRwczovL3N1cHBvcnQuMTB4Z2Vub21pY3MuY29tL3NwYXRpYWwtZ2VuZS1leHByZXNzaW9uL3NvZnR3YXJlL3BpcGVsaW5lcy9sYXRlc3Qvd2hhdC1pcy1zcGFjZS1yYW5nZXIpLiBXZSB3aWxsIGludmVzdGlnYXRlIHRoZSBkYXRhIHNldHMgIGFyZSBhbGwgZnJlZWx5IGF2YWlsYWJsZSBmcm9tIFsxMHggR2Vub21pY3NdKGh0dHBzOi8vc3VwcG9ydC4xMHhnZW5vbWljcy5jb20vc3BhdGlhbC1nZW5lLWV4cHJlc3Npb24vZGF0YXNldHMpLgoKW1NldXJhdCBUdXRvcmlhbF0oaHR0cHM6Ly9zYXRpamFsYWIub3JnL3NldXJhdC92My4xL3NwYXRpYWxfdmlnbmV0dGUuaHRtbCkKCioqVGhpbmdzIHRvIGtub3cgYWJvdXQgdGhpcyB3b3Jrc2hvcCoqCgoxLiBBbGwgZmlsZXMgdGhhdCB3aWxsIGJlIHVzZWQgY2FuIGJlIGZvdW5kIGF0OiBgL21udC9saWJzL3NoYXJlZF9kYXRhL2AKClshW1Rlcm1pbmFsXShodHRwczovL2dpdGh1Yi5jb20vc3RlcGhlbndpbGxpYW1zMjIvU0lCXzIwMjBfV29ya3Nob3AvcmF3L21hc3Rlci9pbWFnZXMvVGVybWluYWwucG5nKV0KCjIuIEdldHRpbmcgc3RhcnRlZCB3aXRoIFIgYW5kIFZpc2l1bSBkYXRhIG91dHNpZGUgb2YgU2V1cmF0IGF0OiBodHRwczovL3N1cHBvcnQuMTB4Z2Vub21pY3MuY29tL3NwYXRpYWwtZ2VuZS1leHByZXNzaW9uL3NvZnR3YXJlL3BpcGVsaW5lcy9sYXRlc3QvcmtpdAozLiBSZWZlcmVuY2UgZ2Vub21lIGZvciBhbGwgc2FtcGxlcyBpcyBHUkNoMzgvbW0xMAo0LiBBbGwgMTB4IHNvZnR3YXJlIGluY2x1ZGluZyBbU3BhY2VyYW5nZXJdKGh0dHBzOi8vc3VwcG9ydC4xMHhnZW5vbWljcy5jb20vc3BhdGlhbC1nZW5lLWV4cHJlc3Npb24vc29mdHdhcmUvcGlwZWxpbmVzL2xhdGVzdC93aGF0LWlzLXNwYWNlLXJhbmdlciksIGFuZCBbTG91cGUgQnJvd3Nlcl0oaHR0cHM6Ly9zdXBwb3J0LjEweGdlbm9taWNzLmNvbS9zcGF0aWFsLWdlbmUtZXhwcmVzc2lvbi9zb2Z0d2FyZS92aXN1YWxpemF0aW9uL2xhdGVzdC93aGF0LWlzLWxvdXBlLWJyb3dzZXIpLCBjYW4gYmUgZG93bmxvYWRlZCBmcm9tIHRoZSBbMTB4IFN1cHBvcnQgU2l0ZV0oaHR0cHM6Ly9zdXBwb3J0LjEweGdlbm9taWNzLmNvbS8pCjUuIE1vc3QgU2V1cmF0IGZpZ3VyZXMgY2FuIGJlIGNvbnRyb2xsZWQgd2l0aCBwYXRjaHdvcmsgYmVjYXVzZSB0aGV5IGFyZSBmdW5kYW1lbnRhbGx5IGdncGxvdCBvYmplY3RzLiBTb21lIHJlYWxseSBuaWNlIGV4YW1wbGVzIGNhbiBiZSBmb3VuZCBvbiB0aGUgW1BhdGNod29yayBHaXRIdWJdKGh0dHBzOi8vcGF0Y2h3b3JrLmRhdGEtaW1hZ2luaXN0LmNvbS9hcnRpY2xlcy9ndWlkZXMvbGF5b3V0Lmh0bWwpCgoKIyAqKkV4cGxvcmluZyBWaXNpdW0gRGF0YSB3aXRoIFNldXJhdCoqCgojIyBMb2FkIG91ciBwYWNrYWdlcwpgYGB7ciBMaWJyYXJpZXMsIGVjaG89VFJVRSwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0KbGlicmFyeShTZXVyYXQpCmxpYnJhcnkoZ2dwbG90MikKbGlicmFyeShwYXRjaHdvcmspCmxpYnJhcnkoZHBseXIpCmxpYnJhcnkoUkNvbG9yQnJld2VyKQpgYGAKCiMjIExvYWRpbmcgZGF0YSBpbiBhIFNldXJhdCBvYmplY3QKClJlYWwgRGF0YXNldCBmb3IgdGhlIHR1dG9yaWFsCmBgYHtyIGV2YWw9RkFMU0V9CmJyZWFzdF9jYW5jZXIgPC0gTG9hZDEwWF9TcGF0aWFsKGRhdGEuZGlyID0gIi9tbnQvbGlicy9zaGFyZWRfZGF0YS9odW1hbl9icmVhc3RfY2FuY2VyXzEvb3V0cy8iLAogICAgICAgICAgICAgICAgZmlsZW5hbWUgPSAiVjFfQnJlYXN0X0NhbmNlcl9CbG9ja19BX1NlY3Rpb25fMV9maWx0ZXJlZF9mZWF0dXJlX2JjX21hdHJpeC5oNSIpCmBgYAoKClNhbWUgZGF0YSBqdXN0IGludGVybmFsIHRvIDEweApgYGB7cn0KYnJlYXN0X2NhbmNlciA8LSBMb2FkMTBYX1NwYXRpYWwoZGF0YS5kaXIgPSAiL21udC9hbmFseXNpcy9tYXJzb2MvcGlwZXN0YW5jZXMvSFdIVEZEU1hYL1NQQVRJQUxfUk5BX0NPVU5URVJfUEQvMTYzMDg2L0hFQUQvb3V0cy8iLCBzbGljZSA9ICJzbGljZTEiKQpgYGAKClRoZXJlIGFyZSBhIGJ1bmNoIG9mIGRhdGEgc2V0cyBob3N0ZWQgYnkgdGhlIFNhdGlqYSBsYWIgaW4gdGhlIFtTZXVyYXQgRGF0YSBQYWNrYWdlXShodHRwczovL2dpdGh1Yi5jb20vc2F0aWphbGFiL3NldXJhdC1kYXRhKS4KCiMgKipSZXN1bHRzKioKIyMgUUMKTGV0J3MgaGF2ZSBhIGxvb2sgYXQgc29tZSBiYXNpYyBRQyBpbmZvcm1hdGlvbi4gS2VlcCBpbiBtaW5kIHRoYXQgbW9zdCBTZXVyYXQgcGxvdHMgYXJlIGdncGxvdCBvYmplY3QgYW5kIGNhbiBiZSBtYW5pcHVsYXRlZCBhcyBzdWNoLgoKQ291bnRzID0gVU1JCkZlYXR1cmVzID0gR2VuZXMKYGBge3IsIGZpZy53aWR0aD0xMCxmaWcuaGVpZ2h0PTgsIHdhcm5pbmc9RkFMU0V9CnBsb3QxIDwtIFZsblBsb3QoYnJlYXN0X2NhbmNlciwgZmVhdHVyZXMgPSAibkNvdW50X1NwYXRpYWwiLCBwdC5zaXplID0gMC4xKSArIAogIGdndGl0bGUoIlVNSSIpICsKICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfYmxhbmsoKSwgCiAgICAgICAgYXhpcy50aXRsZS54ID0gZWxlbWVudF9ibGFuaygpLCAKICAgICAgICBsZWdlbmQucG9zaXRpb24gPSAicmlnaHQiKSArCiAgTm9MZWdlbmQoKQoKcGxvdDIgPC0gVmxuUGxvdChicmVhc3RfY2FuY2VyLCBmZWF0dXJlcyA9ICJuRmVhdHVyZV9TcGF0aWFsIiwgcHQuc2l6ZSA9IDAuMSkgKyAKICBnZ3RpdGxlKCJHZW5lcyIpICsKICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfYmxhbmsoKSwgCiAgICAgICAgYXhpcy50aXRsZS54ID0gZWxlbWVudF9ibGFuaygpLCAKICAgICAgICBsZWdlbmQucG9zaXRpb24gPSAicmlnaHQiKSArCiAgTm9MZWdlbmQoKQoKcGxvdDMgPC0gU3BhdGlhbEZlYXR1cmVQbG90KGJyZWFzdF9jYW5jZXIsIGZlYXR1cmVzID0gIm5Db3VudF9TcGF0aWFsIikgKyAKICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAicmlnaHQiKQoKcGxvdDQgPC0gU3BhdGlhbEZlYXR1cmVQbG90KGJyZWFzdF9jYW5jZXIsIGZlYXR1cmVzID0gIm5GZWF0dXJlX1NwYXRpYWwiKSArCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gInJpZ2h0IikKCnBsb3QxICsgcGxvdDIgKyBwbG90MyAgKyBwbG90NCArIHBsb3RfbGF5b3V0KG5yb3cgPSAyLCBuY29sID0gMikKYGBgCgojIyBOb3JtYWxpemF0aW9uCgpTcGFjZXJhbmdlciBkb2VzIG5vcm1hbGl6YXRpb24gZm9yIGNsdXN0ZXJpbmcgYW5kIERFIGJ1dCBkb2VzIG5vdCByZXR1cm4gdGhhdCBub3JtYWxpemVkIG1hdHJpeAoKUHJlLW5vcm1hbGl6YXRpb24gClJhdyBVTUkgY291bnRzCmBgYHtyLCBmaWcud2lkdGg9MTAsIHdhcm5pbmc9RkFMU0V9ClNwYXRpYWxGZWF0dXJlUGxvdChicmVhc3RfY2FuY2VyLCBmZWF0dXJlcyA9IGMoIkVSQkIyIiwgIkNEOEEiKSkKYGBgCgojIyMgU0UgdHJhbnNmb3JtCgorICBUaGlzIHdpbGwgdGFrZSB+My00IG1pbi4gCgpEb24ndCB3b3JyeSBhYm91dCBgcmVhY2hlZGl0ZXJhdGlvbiBsaW1pdGAgd2FybmluZ3MuIFNlZSBodHRwczovL2dpdGh1Yi5jb20vQ2hyaXN0b3BoSC9zY3RyYW5zZm9ybS9pc3N1ZXMvMjUgZm9yIGRpc2N1c3Npb24KCkRlZmF1bHQgYXNzYXkgd2lsbCBub3cgYmUgc2V0IHRvIFNDVApgYGB7ciwgd2FybmluZz1GQUxTRX0KYnJlYXN0X2NhbmNlciA8LSBTQ1RyYW5zZm9ybShicmVhc3RfY2FuY2VyLCBhc3NheSA9ICJTcGF0aWFsIiwgdmVyYm9zZSA9IFRSVUUpCmBgYAoKYGBge3IsIGZpZy53aWR0aD0xMCwgd2FybmluZz1GQUxTRX0KU3BhdGlhbEZlYXR1cmVQbG90KGJyZWFzdF9jYW5jZXIsIGZlYXR1cmVzID0gYygiRVJCQjIiLCAiQ0Q4QSIpKQpgYGAKCgpGcm9tIFNldXJhdDogCgpUaGUgZGVmYXVsdCBwYXJhbWV0ZXJzIGluIFNldXJhdCBlbXBoYXNpemUgdGhlIHZpc3VhbGl6YXRpb24gb2YgbW9sZWN1bGFyIGRhdGEuIEhvd2V2ZXIsIHlvdSBjYW4gYWxzbyBhZGp1c3QgdGhlIHNpemUgb2YgdGhlIHNwb3RzIChhbmQgdGhlaXIgdHJhbnNwYXJlbmN5KSB0byBpbXByb3ZlIHRoZSB2aXN1YWxpemF0aW9uIG9mIHRoZSBoaXN0b2xvZ3kgaW1hZ2UsIGJ5IGNoYW5naW5nIHRoZSBmb2xsb3dpbmcgcGFyYW1ldGVyczoKCiAgICBwdC5zaXplLmZhY3Rvci0gVGhpcyB3aWxsIHNjYWxlIHRoZSBzaXplIG9mIHRoZSBzcG90cy4gRGVmYXVsdCBpcyAxLjYKICAgIGFscGhhIC0gbWluaW11bSBhbmQgbWF4aW11bSB0cmFuc3BhcmVuY3kuIERlZmF1bHQgaXMgYygxLCAxKS4KICAgIFRyeSBzZXR0aW5nIHRvIGFscGhhIGMoMC4xLCAxKSwgdG8gZG93bndlaWdodCB0aGUgdHJhbnNwYXJlbmN5IG9mIHBvaW50cyB3aXRoIGxvd2VyIGV4cHJlc3Npb24KCgoKYGBge3IsIGZpZy53aWR0aD0xMCwgd2FybmluZz1GQUxTRX0KcDEgPC0gU3BhdGlhbEZlYXR1cmVQbG90KGJyZWFzdF9jYW5jZXIsIGZlYXR1cmVzID0gIklHRkJQNSIsIHB0LnNpemUuZmFjdG9yID0gMSkrIAogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJyaWdodCIpICsKICBnZ3RpdGxlKCJBY3R1YWwgU3BvdCBTaXplIikKcDIgPC0gU3BhdGlhbEZlYXR1cmVQbG90KGJyZWFzdF9jYW5jZXIsIGZlYXR1cmVzID0gIklHRkJQNSIpKyAKICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAicmlnaHQiKSArCiAgZ2d0aXRsZSgiU2NhbGVkIFNwb3QgU2l6ZSIpCnAxICsgcDIKYGBgCgojIyMgRGltZW5zaW9uYWxpdHkgcmVkdWN0aW9uLCBjbHVzdGVyaW5nLCBhbmQgdmlzdWFsaXphdGlvbgoKV2UgY2FuIHRoZW4gcHJvY2VlZCB0byBydW4gZGltZW5zaW9uYWxpdHkgcmVkdWN0aW9uIGFuZCBjbHVzdGVyaW5nIG9uIHRoZSBSTkEgZXhwcmVzc2lvbiBkYXRhLCB1c2luZyB0aGUgc2FtZSB3b3JrZmxvdyBhcyB3ZSB1c2UgZm9yIHNjUk5BLXNlcSBhbmFseXNpcy4KClNvbWUgb2YgdGhlc2UgcHJvY2Vzc2VzIGNhbiBiZSBwYXJhbGxpemVkCgpgYGB7ciBldmFsPUZBTFNFLCBpbmNsdWRlPVRSVUV9CmxpYnJhcnkoZnV0dXJlKQojIGNoZWNrIHRoZSBjdXJyZW50IGFjdGl2ZSBwbGFuCnBsYW4oKQpgYGAKCmBgYHtyIGV2YWw9RkFMU0UsIGluY2x1ZGU9VFJVRX0KIyBjaGFuZ2UgdGhlIGN1cnJlbnQgcGxhbiB0byBhY2Nlc3MgcGFyYWxsZWxpemF0aW9uCnBsYW4oIm11bHRpcHJvY2VzcyIsIHdvcmtlcnMgPSA0KQpwbGFuKCkKYGBgCgoKVGhlIGRlZmF1bHQgVU1BUCBjYWxjdWxhdGlvbiBpcyBwZXJmb3JtZWQgd2l0aCB0aGUgW1ItYmFzZWQgVVdPVF0oaHR0cHM6Ly9jcmFuLnItcHJvamVjdC5vcmcvd2ViL3BhY2thZ2VzL3V3b3QvaW5kZXguaHRtbCkgbGlicmFyeSBIb3dldmVyLCB5b3UgY2FuIHJ1biBVTUFQIGluIHB5dGhvbiB2aWEgcmV0aWN1bGF0ZSBsaWJyYXJ5IGFuZCBgdW1hcC1sZWFybmAuIFdlIGhhdmUgZm91bmQgdGhhdCBmb3Igc21hbGxlciBkYXRhIHNldHMgKDw9IDEwayBjZWxscy9zcG90cykgVVdPVCBpcyBncmVhdC4gRm9yIG11Y2ggbGFyZ2VyIGRhdGEgc2V0cyAoMTAwayArIGNlbGxzL3Nwb3RzKSBgdW1hcC1sZWFybmAgY2FuIGJlIGEgZmFzdGVyIG9wdGlvbi4KCmBgYHtyfQpicmVhc3RfY2FuY2VyIDwtIFJ1blBDQShicmVhc3RfY2FuY2VyLCBhc3NheSA9ICJTQ1QiLCB2ZXJib3NlID0gRkFMU0UpCmJyZWFzdF9jYW5jZXIgPC0gRmluZE5laWdoYm9ycyhicmVhc3RfY2FuY2VyLCByZWR1Y3Rpb24gPSAicGNhIiwgZGltcyA9IDE6MzApCmJyZWFzdF9jYW5jZXIgPC0gRmluZENsdXN0ZXJzKGJyZWFzdF9jYW5jZXIsIHZlcmJvc2UgPSBGQUxTRSkKYnJlYXN0X2NhbmNlciA8LSBSdW5VTUFQKGJyZWFzdF9jYW5jZXIsIHJlZHVjdGlvbiA9ICJwY2EiLCBkaW1zID0gMTozMCkKYGBgCgpOb3cgbGV0J3MgaGF2ZSBhIGxvb2sgYXQgdGhlIGNsdXN0ZXJpbmcKCmBgYHtyLCBmaWcud2lkdGg9OH0KRGltUGxvdChicmVhc3RfY2FuY2VyLCByZWR1Y3Rpb24gPSAidW1hcCIsIGxhYmVsID0gRkFMU0UsKSArCiAgbGFicyhjb2xvciA9ICJDbHVzdGVyIikKYGBgCgpgYGB7ciwgZmlnLndpZHRoPTEwLGZpZy5oZWlnaHQ9MTAsIHdhcm5pbmc9RkFMU0V9CnAxIDwtIERpbVBsb3QoYnJlYXN0X2NhbmNlciwgcmVkdWN0aW9uID0gInVtYXAiLCBsYWJlbCA9IFRSVUUpICsKICBsYWJzKGNvbG9yID0gIkNsdXN0ZXIiKQpwMiA8LSBTcGF0aWFsRGltUGxvdChicmVhc3RfY2FuY2VyLCBsYWJlbCA9IFRSVUUsIGxhYmVsLnNpemUgPSAzKSArCiAgbGFicyhmaWxsID0gIkNsdXN0ZXIiKQoKcDEgKyBwMiArIHBsb3RfYW5ub3RhdGlvbigKICB0aXRsZSA9ICdDbHVzdGVyaW5nIGluIFVNQVAgYW5kIFRpc3N1ZSBTcGFjZScsCiAgY2FwdGlvbiA9ICdQcm9jZXNzZWQgYnkgU3BhY2VyYW5nZXIgMS4xXG5Ob3JtaWxpemF0aW9uIGFuZCBDbHVzdGVyaW5nIGJ5IFNldXJhdCcKKSArIHBsb3RfbGF5b3V0KG5yb3cgPSAxKQpgYGAKCkkgZG9uJ3QgcmVhbGx5IGxpa2UgdGhlc2UgY29sb3JzIHNvIGxldCdzIGNoYW5nZSB0aGVtCmBgYHtyfQpteVBhbGV0dGUgPC0gY29sb3JSYW1wUGFsZXR0ZShyZXYoYnJld2VyLnBhbCgxMSwgIlNwZWN0cmFsIikpKQpgYGAKCmBgYHtyLCBmaWcud2lkdGg9MTAsIGZpZy5oZWlnaHQ9MTAsIHdhcm5pbmc9RkFMU0V9CnAxIDwtIERpbVBsb3QoYnJlYXN0X2NhbmNlciwgcmVkdWN0aW9uID0gInVtYXAiLCBsYWJlbCA9IFRSVUUpICsKICBsYWJzKGNvbG9yID0gIkNsdXN0ZXIiKSArIAogIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBjKCIjYjJkZjhhIiwiI2U0MWExYyIsIiMzNzdlYjgiLCIjNGRhZjRhIiwiI2ZmN2YwMCIsImdvbGQiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIjYTY1NjI4IiwgIiM5OTk5OTkiLCAiYmxhY2siLCAicGluayIsICJwdXJwbGUiLCAiYnJvd24iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImdyZXkiLCAieWVsbG93IiwgImdyZWVuIikpCgpwMiA8LSBTcGF0aWFsRGltUGxvdChicmVhc3RfY2FuY2VyLCBsYWJlbCA9IFRSVUUsIGxhYmVsLnNpemUgPSAzKSArCiAgbGFicyhmaWxsID0gIkNsdXN0ZXIiKSsgCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gYygiI2IyZGY4YSIsIiNlNDFhMWMiLCIjMzc3ZWI4IiwiIzRkYWY0YSIsIiNmZjdmMDAiLCJnb2xkIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiI2E2NTYyOCIsICIjOTk5OTk5IiwgImJsYWNrIiwgInBpbmsiLCAicHVycGxlIiwgImJyb3duIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJncmV5IiwgInllbGxvdyIsICJncmVlbiIpKQoKcDEgKyBwMiArIHBsb3RfYW5ub3RhdGlvbigKICB0aXRsZSA9ICdDbHVzdGVyaW5nIGluIFVNQVAgYW5kIFRpc3N1ZSBTcGFjZScsCiAgY2FwdGlvbiA9ICdQcm9jZXNzZWQgYnkgU3BhY2VyYW5nZXIgMS4xXG5Ob3JtaWxpemF0aW9uIGFuZCBDbHVzdGVyaW5nIGJ5IFNldXJhdCcKKSArIHBsb3RfbGF5b3V0KG5yb3cgPSAxKQpgYGAKCklmIGludGVyZXN0ZWQgeW91IGNhbiBhbHNvIG5vdyBsb29rIGF0IFVNSSBhbmQgR2VuZSBjb3VudHMgcGVyIGNsdXN0ZXIgYXMgd2VsbApgYGB7cn0KcGxvdDEgPC0gVmxuUGxvdChicmVhc3RfY2FuY2VyLCBmZWF0dXJlcyA9ICJuQ291bnRfU3BhdGlhbCIsIHB0LnNpemUgPSAwLjEpICsgCiAgZ2d0aXRsZSgiVU1JIikgKwogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IGMoIiNiMmRmOGEiLCIjZTQxYTFjIiwiIzM3N2ViOCIsIiM0ZGFmNGEiLCIjZmY3ZjAwIiwiZ29sZCIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIiNhNjU2MjgiLCAiIzk5OTk5OSIsICJibGFjayIsICJwaW5rIiwgInB1cnBsZSIsICJicm93biIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiZ3JleSIsICJ5ZWxsb3ciLCAiZ3JlZW4iKSkrCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X2JsYW5rKCksIAogICAgICAgIGF4aXMudGl0bGUueCA9IGVsZW1lbnRfYmxhbmsoKSwgCiAgICAgICAgbGVnZW5kLnBvc2l0aW9uID0gInJpZ2h0IikgKwogIE5vTGVnZW5kKCkKCnBsb3QyIDwtIFZsblBsb3QoYnJlYXN0X2NhbmNlciwgZmVhdHVyZXMgPSAibkZlYXR1cmVfU3BhdGlhbCIsIHB0LnNpemUgPSAwLjEpICsgCiAgZ2d0aXRsZSgiR2VuZXMiKSArCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gYygiI2IyZGY4YSIsIiNlNDFhMWMiLCIjMzc3ZWI4IiwiIzRkYWY0YSIsIiNmZjdmMDAiLCJnb2xkIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiI2E2NTYyOCIsICIjOTk5OTk5IiwgImJsYWNrIiwgInBpbmsiLCAicHVycGxlIiwgImJyb3duIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJncmV5IiwgInllbGxvdyIsICJncmVlbiIpKSsKICB0aGVtZShheGlzLnRpdGxlLnggPSBlbGVtZW50X2JsYW5rKCksIAogICAgICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICJyaWdodCIpICsKICBOb0xlZ2VuZCgpCgpwbG90MSArIHBsb3QyCmBgYAoKCk5vdyBsZXQncyB0YWtlIGEgbG9vayBhdCBhdCBhIGdlbmUgb2YgaW50ZXJlc3Qgd2l0aCB2aW9saW4gcGxvdHMgYnV0IGFsc28gaW4gaW1hZ2Ugc3BhY2UuCmBgYHtyLCBmaWcud2lkdGg9OCwgZmlnLmhlaWdodD04fQpwMSA8LSBWbG5QbG90KGJyZWFzdF9jYW5jZXIsIGZlYXR1cmVzID0gIklHRkJQNSIsIHB0LnNpemUgPSAwLjEpICsgCiAgZ2d0aXRsZSgiSUdGQlA1IikgKwogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IGMoIiNiMmRmOGEiLCIjZTQxYTFjIiwiIzM3N2ViOCIsIiM0ZGFmNGEiLCIjZmY3ZjAwIiwiZ29sZCIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIiNhNjU2MjgiLCAiIzk5OTk5OSIsICJibGFjayIsICJwaW5rIiwgInB1cnBsZSIsICJicm93biIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiZ3JleSIsICJ5ZWxsb3ciLCAiZ3JlZW4iKSkrCiAgdGhlbWUoYXhpcy50aXRsZS54ID0gZWxlbWVudF9ibGFuaygpLCAKICAgICAgICBsZWdlbmQucG9zaXRpb24gPSAicmlnaHQiKSArCiAgTm9MZWdlbmQoKSArCiAgc3RhdF9zdW1tYXJ5KGZ1bj1tZWFuLCBnZW9tPSJwb2ludCIsIHNoYXBlPTIzLCBzaXplPTQsIGNvbG9yPSJyZWQiKQoKcDIgPC0gU3BhdGlhbEZlYXR1cmVQbG90KGJyZWFzdF9jYW5jZXIsIGZlYXR1cmVzID0gIklHRkJQNSIpKyAKICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAicmlnaHQiKQoKcDMgPC0gU3BhdGlhbERpbVBsb3QoYnJlYXN0X2NhbmNlciwgbGFiZWwgPSBUUlVFLCBsYWJlbC5zaXplID0gMykgKwogIGxhYnMoZmlsbCA9ICJDbHVzdGVyIikrIAogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IGMoIiNiMmRmOGEiLCIjZTQxYTFjIiwiIzM3N2ViOCIsIiM0ZGFmNGEiLCIjZmY3ZjAwIiwiZ29sZCIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIiNhNjU2MjgiLCAiIzk5OTk5OSIsICJibGFjayIsICJwaW5rIiwgInB1cnBsZSIsICJicm93biIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiZ3JleSIsICJ5ZWxsb3ciLCAiZ3JlZW4iKSkgKwogIE5vTGVnZW5kKCkKCnJvdzEgPC0gcDIgKyBwMyArIHBsb3RfbGF5b3V0KG5yb3cgPSAxKQpyb3cxICsgcDErIHBsb3RfbGF5b3V0KG5yb3cgPSAyLCB3aWR0aHMgPSBjKDAuNSwgMC41KSkKYGBgCgpXZSBjYW4gYWxzbyBsb29rIGF0IHRoZXNlIGRhdGEgaW50ZXJhY3RpdmVseQpgYGB7ciBldmFsPUZBTFNFLCBpbmNsdWRlPVRSVUV9CkxpbmtlZERpbVBsb3QoYnJlYXN0X2NhbmNlcikKYGBgCgojIyBTcGF0aWFsbHkgdmFyaWFibGUgZmVhdHVyZXMKCkZpcnN0IHdlJ2xsIGlkZW50aWZ5IGRlZmVyZW50aWFsbHkgZXhwcmVzc2VkIGdlbmVzLiAKClBhcmFsbGVsaXphdGlvbiBoZWxwcyBoZXJlIHRvbyBsZXQncyBtYWtlIHN1cmUgb3VyIHBsYW4gaXMgc3RpbGwgaW50YWN0CgpgYGB7ciwgZXZhbD1GQUxFLCBpbmNsdWRlPVRSVUV9CnBsYW4oKQpgYGAKYC0gY2FsbDogcGxhbigibXVsdGlwcm9jZXNzIiwgd29ya2VycyA9IDQpYCBpbmRpY2F0ZXMgdGhhdCBpdCBpcwoKTG9va3MgbGlrZSB3ZSBoYXZlIHNvbWUgdmVyeSBERSBnZW5lcyBmb3IgY2x1c3RlcnMgNCBhbmQgMTEKCgpjbGFyaWZ5IHdoYXQgaWRlbnQuMSA9IDQsIGlkZW50LjIgPSA2IGFyZSBmb3IKYGBge3IsIGZpZy53aWR0aD0xMCwgd2FybmluZz1GQUxTRSwgbWVzc2FnZT1GQUxTRX0KZGVfbWFya2VycyA8LSBGaW5kTWFya2VycyhicmVhc3RfY2FuY2VyLCBpZGVudC4xID0gNCwgaWRlbnQuMiA9IDYpCmRlX21hcmtlcnMKYGBgCgojIyBJZGVudGlmeSB0aGUgbW9zdCB1cC1yZWd1bGF0ZWQgYW5kIGRvd24tcmVndWxhdGVkIGdlbmVzCmBgYHtyfQpkZV9tYXJrZXJzX3VwIDwtIGRlX21hcmtlcnMgJT4lCiAgdGliYmxlOjpyb3duYW1lc190b19jb2x1bW4odmFyID0gIkdlbmUiKSAlPiUgCiAgYXJyYW5nZSgtYXZnX2xvZ0ZDKQoKZGVfbWFya2Vyc19kb3duIDwtIGRlX21hcmtlcnMgJT4lCiAgdGliYmxlOjpyb3duYW1lc190b19jb2x1bW4odmFyID0gIkdlbmUiKSAlPiUgCiAgYXJyYW5nZShhdmdfbG9nRkMpCmBgYAoKCiMjIyBNb3N0IHVwLXJlZ3VsYXRlZCBnZW5lcwpgYGB7ciwgZmlnLndpZHRoPTEwLCBmaWcuaGVpZ2h0PTEwLCB3YXJuaW5nPUZBTFNFfQpTcGF0aWFsRmVhdHVyZVBsb3Qob2JqZWN0ID0gYnJlYXN0X2NhbmNlciwgZmVhdHVyZXMgPSBkZV9tYXJrZXJzX3VwJEdlbmVbMToxMF0sIGFscGhhID0gYygwLjEsIDEpLCBuY29sID0gMykKYGBgCgojIyMgTW9zdCBkb3duLXJlZ3VsYXRlZCBnZW5lcwpgYGB7ciwgZmlnLndpZHRoPTEwLCBmaWcuaGVpZ2h0PTEwLCB3YXJuaW5nPUZBTFNFfQpTcGF0aWFsRmVhdHVyZVBsb3Qob2JqZWN0ID0gYnJlYXN0X2NhbmNlciwgZmVhdHVyZXMgPSBkZV9tYXJrZXJzX2Rvd24kR2VuZVsxOjEwXSwgYWxwaGEgPSBjKDAuMSwgMSksIG5jb2wgPSAzKQpgYGAKCndoYXQgYXJlIHRoZSB0b3AgdmFyaWFibGUgZmVhdHVyZXM/CmBgYHtyfQpWYXJpYWJsZUZlYXR1cmVzKGJyZWFzdF9jYW5jZXIpWzE6MTBdCmBgYAoKd2hhdCBhcmUgdGhlIHRvcCBERSBnZW5lcz8KYGBge3J9CnJvd25hbWVzKGRlX21hcmtlcnMpWzE6MTBdCmBgYAoKIyMgU3BhdGlhbGx5IFZhcmlhYmxlIEdlbmVzCgpTbyB3aGF0IGFib3V0IHNwYXRpYWwgZW5yaWNobWVudD8gCgpTb21lIG1ldGhvZHMKCjEuIFtUcmVuZHNjZWVrXShodHRwczovL3d3dy5uYXR1cmUuY29tL2FydGljbGVzL25tZXRoLjQ2MzQpCjIuIFtTcGxvdGNoXShodHRwczovL3d3dy5iaW9yeGl2Lm9yZy9jb250ZW50LzEwLjExMDEvNzU3MDk2djEpCjMuIFtTUEFSS10oaHR0cHM6Ly93d3cubmF0dXJlLmNvbS9hcnRpY2xlcy9zNDE1OTItMDE5LTA3MDEtNykKNC4gW1NwYXRpYWxERV0oaHR0cHM6Ly93d3cubmF0dXJlLmNvbS9hcnRpY2xlcy9ubWV0aC40NjM2KQogICsgV2UgaGF2ZSBmb3VuZCB0aGlzIGltcGxlbWVudGF0aW9uIG5vdCB0byBiZSB2ZXJ5IGVmZmVjdGl2ZS4gSXQncyBhbHNvIG5vdCB1bmRlciBhY3RpdmUgZGV2ZWxvcG1lbnQKCgpVc2luZyB0aGUgdG9wIDEwMCB2YXJpYWJsZSBnZW5lcyBmaW5kIHNwYXRpYWxseSBlbnJpY2hlZCBvbmVzLiBOb3RlIHRoYXQgaW4gdGhlIFNldXJhdCBTcGF0aWFsIFR1dG9yaWFsIHRoZXkgdXNlIDEwMDAgZ2VuZXMuIFlvdSBjYW4gYWxzbyB1c2UgYWxsIGdlbmVzIGJ1dCB0aGF0IHdpbGwgdGFrZSBhIGxvbmcgdGltZS4gVXNpbmcgYSBjYWxjdWxhdGlvbiBvZiBbTW9yYW5zIEldKGh0dHBzOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL01vcmFuJTI3c19JKSBjYW4gc29tZXRpbWVzIGJlIGEgZmFzdGVyIGFwcHJvYWNoLCBlc3BlY2lhbGx5IGlmIHlvdSBhcmUgdXNpbmcgcGFyYWxsaXphdGlvbi4KCgpgYGB7cn0KYnJlYXN0X2NhbmNlciA8LSBGaW5kU3BhdGlhbGx5VmFyaWFibGVGZWF0dXJlcyhicmVhc3RfY2FuY2VyLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhc3NheSA9ICJTQ1QiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzbG90ID0gInNjYWxlLmRhdGEiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmZWF0dXJlcyA9IFZhcmlhYmxlRmVhdHVyZXMoYnJlYXN0X2NhbmNlcilbMToxMDBdLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlbGVjdGlvbi5tZXRob2QgPSAibWFya3ZhcmlvZ3JhbSIsIHZlcmJvc2UgPSBUUlVFKQpgYGAKCkhhdmUgYSBsb29rIGF0IHRoZSBzcGF0aWFsbHkgdmFyaWFibGUgZ2VuZXMgY2FsY3VsYXRlZCBieSBgbWFya3ZhcmlvZ3JhbWAgb3JkZXJlZCBmcm9tIG1vc3QgdmFyaWFibGUgdG8gbGVhc3QgdmFyaWFibGUKYGBge3J9ClNwYXRpYWxseVZhcmlhYmxlRmVhdHVyZXMoYnJlYXN0X2NhbmNlciwgc2VsZWN0aW9uLm1ldGhvZCA9ICJtYXJrdmFyaW9ncmFtIiwgZGVjcmVhc2luZyA9IFRSVUUpCmBgYAoKYGBge3IsIGZpZy53aWR0aD0xMCwgZmlnLmhlaWdodD04LCB3YXJuaW5nPUZBTFNFfQp0b3AuZmVhdHVyZXNfdHJlbmRzZXEgPC0gaGVhZChTcGF0aWFsbHlWYXJpYWJsZUZlYXR1cmVzKGJyZWFzdF9jYW5jZXIsIHNlbGVjdGlvbi5tZXRob2QgPSAibWFya3ZhcmlvZ3JhbSIpLCA4KQpTcGF0aWFsRmVhdHVyZVBsb3QoYnJlYXN0X2NhbmNlciwgZmVhdHVyZXMgPSB0b3AuZmVhdHVyZXNfdHJlbmRzZXEsIG5jb2wgPSA0LCBhbHBoYSA9IGMoMC4xLCAxKSkKYGBgCgpNb3JhbidzIEkgaW1wbGVtZW50YXRpb24uIEZvciBvdGhlciBzcGF0aWFsIGRhdGEgdHlwZXMgdGhlIHguY3V0cyBhbmQgeS5jdXRzIGRldGVybWluZXMgdGhlIGdyaWQgdGhhdCBpcyBsYWlkIG92ZXIgdGhlIHRpc3N1ZSBpbiB0aGUgY2FwdHVyZSBhcmVhLiBIZXJlIHdlJ2xsIHJlbW92ZSB0aG9zZQpgYGB7cn0KYnJlYXN0X2NhbmNlciA8LSBGaW5kU3BhdGlhbGx5VmFyaWFibGVGZWF0dXJlcyhicmVhc3RfY2FuY2VyLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhc3NheSA9ICJTQ1QiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzbG90ID0gInNjYWxlLmRhdGEiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmZWF0dXJlcyA9IFZhcmlhYmxlRmVhdHVyZXMoYnJlYXN0X2NhbmNlcilbMToxMDBdLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlbGVjdGlvbi5tZXRob2QgPSAibW9yYW5zaSIpCmBgYAoKCkhhdmUgYSBsb29rIGF0IHRoZSBzcGF0aWFsbHkgdmFyaWFibGUgZ2VuZXMgY2FsY3VsYXRlZCBieSBgbW9yYW5zaWAgb3JkZXJlZCBmcm9tIG1vc3QgdmFyaWFibGUgdG8gbGVhc3QgdmFyaWFibGUKCmBgYHtyfQpTcGF0aWFsbHlWYXJpYWJsZUZlYXR1cmVzKGJyZWFzdF9jYW5jZXIsIHNlbGVjdGlvbi5tZXRob2QgPSAibW9yYW5zaSIsIGRlY3JlYXNpbmcgPSBUUlVFKQpgYGAKCmBgYHtyLCBmaWcud2lkdGg9MTAsIGZpZy5oZWlnaHQ9OCwgd2FybmluZz1GQUxTRX0KdG9wLmZlYXR1cmVzX21vcmFuc2kgPC0gaGVhZChTcGF0aWFsbHlWYXJpYWJsZUZlYXR1cmVzKGJyZWFzdF9jYW5jZXIsIHNlbGVjdGlvbi5tZXRob2QgPSAibW9yYW5zaSIpLCA4KQpTcGF0aWFsRmVhdHVyZVBsb3QoYnJlYXN0X2NhbmNlciwgZmVhdHVyZXMgPSB0b3AuZmVhdHVyZXNfbW9yYW5zaSwgbmNvbCA9IDQsIGFscGhhID0gYygwLjEsIDEpKQpgYGAKCldlIGNhbiBzZWUgdGhhdCB0aGUgcmVzdWx0cyBhcmUgc2xpZ2h0bHkgZGlmZmVyZW50LiBTbyBsZXQncyB0YWtlIGEgbG9vayBhdCB3aHkuCgpgYGB7cn0Kc3BhdGlhbGx5X3ZhcmlhYmxlX2dlbmVzIDwtIGJyZWFzdF9jYW5jZXJAYXNzYXlzJFNDVEBtZXRhLmZlYXR1cmVzICU+JQogIHRpZHlyOjpkcm9wX25hKCkKCnNwYXRpYWxseV92YXJpYWJsZV9nZW5lcwpgYGAKWW91IGNhbiBzZWUgdGhlIHR3byBtZXRob2RzIHNob3cgCmBgYHtyfQptbV9jb3IgPC0gY29yLnRlc3Qoc3BhdGlhbGx5X3ZhcmlhYmxlX2dlbmVzJG1vcmFuc2kuc3BhdGlhbGx5LnZhcmlhYmxlLnJhbmssIHNwYXRpYWxseV92YXJpYWJsZV9nZW5lcyRtYXJrdmFyaW9ncmFtLnNwYXRpYWxseS52YXJpYWJsZS5yYW5rKQpnZ3Bsb3Qoc3BhdGlhbGx5X3ZhcmlhYmxlX2dlbmVzLCBhZXMoeD1tb3JhbnNpLnNwYXRpYWxseS52YXJpYWJsZS5yYW5rLHk9bWFya3ZhcmlvZ3JhbS5zcGF0aWFsbHkudmFyaWFibGUucmFuaykpKwogIGdlb21fcG9pbnQoKSsKICBnZW9tX3Ntb290aCgpKwogIHhsYWIoIk1vcmFucyBJIFJhbmsiKSsKICB5bGFiKCJNYXJrdmFyaW9ncmFtIFJhbmsiKSsKICBhbm5vdGF0ZSgidGV4dCIsIHggPSAyNSwgeSA9IDc1LCBsYWJlbCA9IHBhc3RlKCJQZWFyc29uJ3MgQ29ycmVsYXRpb25cbiIsIHJvdW5kKG1tX2NvciRlc3RpbWF0ZVsxXSwgZGlnaXRzID0gMiksIHNlcCA9ICIiKSkrCiAgdGhlbWVfYncoKQpgYGAKCiMjIENhbmNlciBhbm5vdGF0aW9ucwoKV2hlcmUgYXJlIHRoZXNlIGdlbmVzIGJlaW5nIGV4cHJlc3NlZCByZWxhdGl2ZSB0byBwYXRob2xvZ2lzdCBhbm5vdGF0aW9uPwoKYGBge3IsIGZpZy5oZWlnaHQ9OCwgZmlnLndpZHRoPTh9CmNhIDwtIHJlYWRiaXRtYXA6OnJlYWQuYml0bWFwKCJpbWFnZXMvQnJlYXN0IENhbmNlciBQYXRoLnBuZyIpCiMgaW4gdGhlIHR1dG9yaWFsCiMgY2EgPC0gcmVhZGJpdG1hcDo6cmVhZC5iaXRtYXAoJy9tbnQvbGlicy9zaGFyZWRfZGF0YS9odW1hbl9icmVhc3RfY2FuY2VyXzEvaW1hZ2VzL0JyZWFzdF9DYW5jZXJfUGF0aC5wbmcnKQpwbG90KDA6MSwwOjEsdHlwZT0ibiIsYW5uPUZBTFNFLGF4ZXM9RkFMU0UpCnJhc3RlckltYWdlKGNhLDAsMCwxLDEpCmBgYAoKTG9va3MgbGlrZSB0aGUgIE1hdHJpeCBHbGEgcHJvdGVpbiAoIF9NR1BfICkgZ2VuZSBpcyBlbnJpY2hlZCBpbiBEdWN0YWwgQ2FyY2lub21hIF9JbiBTaXR1Xy4gTm90IGEgbG90IGlzIGtub3duIGFib3V0IF9NR1BfIGluIHRoZSBjb250ZXh0IG9mIGNhbmNlciBidXQgaXQgbG9va3MgbGlrZSBpdCBjb3VsZCBiZSBhbiBpbnRlcmVzdGluZyBub3ZlbCBnZW5lIHRvIGludmVzdGlnYXRlIHdpdGggcmVnYXJkIHRvIER1Y3RhbCBDYXJjaW5vbWEgX0luIFNpdHVfLgoKYGBge3IsIHdhcm5pbmc9RkFMU0V9ClNwYXRpYWxGZWF0dXJlUGxvdChvYmplY3QgPSBicmVhc3RfY2FuY2VyLCBmZWF0dXJlcyA9ICJNR1AiLCBhbHBoYSA9IGMoMC4xLCAxKSwgbmNvbCA9IDMpCmBgYAoKIyBNdWx0aXBsZSBTZWN0aW9ucwoKZm9yIHdvcmtzaG9wCmBgYHtyIGV2YWw9RkFMU0V9CmJyZWFzdF9jYW5jZXJfMiA8LSBMb2FkMTBYX1NwYXRpYWwoZGF0YS5kaXIgPSAiL21udC9saWJzL3NoYXJlZF9kYXRhL2h1bWFuX2JyZWFzdF9jYW5jZXJfMi9vdXRzLyIsCiAgICAgICAgICAgICAgICBmaWxlbmFtZSA9ICJWMV9CcmVhc3RfQ2FuY2VyX0Jsb2NrX0FfU2VjdGlvbl8yX2ZpbHRlcmVkX2ZlYXR1cmVfYmNfbWF0cml4Lmg1IikKYGBgCmZvciAxMHgKYGBge3J9CmJyZWFzdF9jYW5jZXJfMiA8LSBMb2FkMTBYX1NwYXRpYWwoZGF0YS5kaXIgPSAiL21udC9hbmFseXNpcy9tYXJzb2MvcGlwZXN0YW5jZXMvSFdIVEZEU1hYL1NQQVRJQUxfUk5BX0NPVU5URVJfUEQvMTYzMDg3L0hFQUQvb3V0cy8iLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzbGljZSA9ICJzbGljZTIiKQpgYGAKCmBgYHtyfQpicmVhc3RfY2FuY2VyX21lcmdlZCA8LSBtZXJnZShicmVhc3RfY2FuY2VyLCBicmVhc3RfY2FuY2VyXzIpCmBgYAoKQ291bnRzID0gVU1JCkZlYXR1cmVzID0gR2VuZXMKYGBge3IsIGZpZy53aWR0aD0xMCxmaWcuaGVpZ2h0PTEwLCB3YXJuaW5nPUZBTFNFfQpwbG90MSA8LSBTcGF0aWFsRmVhdHVyZVBsb3QoYnJlYXN0X2NhbmNlcl9tZXJnZWQsIGZlYXR1cmVzID0gIm5Db3VudF9TcGF0aWFsIikgKyAKICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAicmlnaHQiKQoKcGxvdDIgPC0gU3BhdGlhbEZlYXR1cmVQbG90KGJyZWFzdF9jYW5jZXJfbWVyZ2VkLCBmZWF0dXJlcyA9ICJuRmVhdHVyZV9TcGF0aWFsIikgKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJyaWdodCIpCgpwbG90MSArIHBsb3QyICsgcGxvdF9sYXlvdXQobnJvdyA9IDIpCmBgYAoKIyMgTm9ybWFsaXplIG1lcmdlZCBkYXRhCgpUaGlzIHdpbGwgdGFrZSB+M21pbgoKRGVmYXVsdCBhc3NheSB3aWxsIG5vdyBiZSBzZXQgdG8gU0NUCmBgYHtyLCB3YXJuaW5nPUZBTFNFfQpicmVhc3RfY2FuY2VyX21lcmdlZCA8LSBTQ1RyYW5zZm9ybShicmVhc3RfY2FuY2VyX21lcmdlZCwgYXNzYXkgPSAiU3BhdGlhbCIsIHZlcmJvc2UgPSBUUlVFKQpgYGAKCmBgYHtyLCBmaWcud2lkdGg9MTAsIHdhcm5pbmc9RkFMU0V9ClNwYXRpYWxGZWF0dXJlUGxvdChicmVhc3RfY2FuY2VyX21lcmdlZCwgZmVhdHVyZXMgPSBjKCJFUkJCMiIsICJDRDhBIikpCmBgYAoKIyBTaW5nbGUgY2VsbC9udWNsZWkgaW5nZWdyYXRpb24KCkhlcmUgd2UgaGF2ZSBhIHByZXByb2Nlc3NlZCBTZXVyYXQgb2JqZWN0IHdpdGggMTBrIG51Y2xlaSBhbm5vdGF0ZWQgZnJvbSBhIGJyZWFzdCBjYW5jZXIgc2FtcGxlLiBEb24ndCBib3RoZXIgdG9vIG11Y2ggd2l0aCB0aGUgZGV0YWlscyBvZiBob3cgdGhpcyBkYXRhIHdhcyBnZW5lcmF0ZWQgdGhleSBkb24ndCBwYXJ0aWN1bGFybHkgbWF0dGVyIGZvciBvdXIgcHVycG9zZXMuIAoKIyMgTG9hZCB0aGUgU2V1cmF0IG9iamVjdAoxMHggaW5mcmFzdHJ1Y3R1cmUKYGBge3J9CmJjX3NuUk5BIDwtIHJlYWRSRFMoIi9tbnQvaG9tZS9zdGVwaGVuLndpbGxpYW1zL3lhcmQvT2Rpbi9TSUJfMjAyMF9Xb3Jrc2hvcC9iY19zblJOQS5yZHMiKQpgYGAKCkZvciB0aGUgd29ya3Nob3AKYGBge3IgZXZhbD1GQUxTRSwgaW5jbHVkZT1UUlVFfQpiY19zblJOQSA8LSByZWFkUkRTKCIvbW50L2xpYnMvc2hhcmVkX2RhdGEvYmNfc25STkEucmRzIikKYGBgCgoKYGBge3J9CmJjX3NuUk5BCmBgYAoKYGBge3IsIGZpZy53aWR0aD0xMH0KRGltUGxvdChiY19zblJOQSwgZ3JvdXAuYnkgPSAic3ViY2xhc3MiLCBsYWJlbCA9IEZBTFNFKQpgYGAK